package com.young.core.manager.impl;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;

import com.young.common.query.Pagination;
import com.young.common.query.Query;

import com.young.core.dao.EventDao;
import com.young.core.dao.JobDao;
import com.young.core.domain.EventDO;
import com.young.core.domain.JobDO;
import com.young.core.manager.JobManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * name: JobInfoManagerImpl
 *
 * @author zhaoxinbo
 * @Description
 * @Date create in 2020/9/21 17:19.
 */
@Component
public class JobManagerImpl implements JobManager {

    private static final String PREFIX_ID = "_JOB_";

    private static final Cache<String, JobDO> JOB_CACHE = CacheBuilder.newBuilder().recordStats()
            .concurrencyLevel(Runtime.getRuntime().availableProcessors() + 2)
            .initialCapacity(128)
            .maximumSize(4096)
            .expireAfterWrite(6, TimeUnit.SECONDS)
            .build();

    @Autowired
    private EventDao eventDao;

    @Autowired
    private JobDao jobDao;


    @Override
    public void insert(JobDO job) {
        this.jobDao.insert(job);

    }

    @Override
    public void update(JobDO job) {
        this.jobDao.update(job);

        invalidate(job.getId(), job.getUniqueCode());
    }

    @Override
    public JobDO get(int id) {
        return jobDao.get(id);
    }

    @Override
    public JobDO getCache(int id) throws ExecutionException {
        return JOB_CACHE.get(key(id), () -> get(id));
    }

    @Override
    public JobDO getCache(String uniqueCode) throws ExecutionException {
        return JOB_CACHE.get(key(uniqueCode), () -> get(uniqueCode));
    }

    @Override
    public JobDO get(String uniqueCode) {
        return jobDao.get(uniqueCode);
    }

    @Override
    public boolean exist(String uniqueCode) {
        return get(uniqueCode) != null;
    }

    @Override
    public void delete(int id) {
        jobDao.delete(id);
    }

    @Override
    public void batchUpdate(String project, Collection<Integer> ids, Map<String, Object> fields) {
        jobDao.batchUpdate(project, ids, fields);
    }

    @Override
    public Pagination<JobDO> query(Query query) {
        return jobDao.query(query);
    }

    @Override
    public void updateStatus(int id, String project, int status, String operator) {
        EventDO event = getOperatorEvent(id, project, status);
        this.eventDao.insert(event);
        this.jobDao.updateStatus(id, status, operator);
    }

    @Override
    public int count(String project) {
        return this.jobDao.count(project);
    }

    @Override
    public List<JobDO> getAll(String project) {
        return jobDao.getAll(project);
    }

    private EventDO getOperatorEvent(int id, String project, int type) {
        EventDO event = new EventDO();
        event.setProject(project);
        event.setJobId(id);
        event.setType(type);
        return event;
    }

    private void invalidate(int id, String uniqueCode) {
        JOB_CACHE.invalidate(key(id));
        JOB_CACHE.invalidate(key(uniqueCode));
    }

    private String key(int id) {
        return PREFIX_ID + id;
    }

    private String key(String uniqueCode) {
        return PREFIX_ID + uniqueCode;
    }

}
